
#import "AmapLocationTool.h"

#import <AMapLocationKit/AMapLocationManager.h>

#include "AppTool.h"

@interface AmapLocationTool () <AMapLocationManagerDelegate>

@property(nonatomic, retain) AMapLocationManager* _locManager;

@end

@implementation AmapLocationTool

-(instancetype)init
{
    self = [super init];
    if (self)
    {
        self._locManager = [[AMapLocationManager alloc]init];
        self._locManager.delegate = self;
    
        //设置不允许系统暂停定位
        [self._locManager setPausesLocationUpdatesAutomatically:NO];
        //设置允许在后台定位
        [self._locManager setAllowsBackgroundLocationUpdates:YES];
        //设置期望定位精度
        [self._locManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
    }
    
    return self;
}

-(void)startOnceLocation
{
    [self._locManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error)
     {
         int code = 0;
         if (error != nil && error.code == AMapLocationErrorLocateFailed)
         {
             //定位错误：此时location和regeocode没有返回值
             code = -1;
             if (AppTool::getInstance()->getAmapLocationDelegate() != NULL)
             {
                 AppTool::getInstance()->getAmapLocationDelegate()->onOnceLocationEnd(-1, 0.0, 0.0, "", "", "", "", "", "", "", "");
             }
         }
         else if (error != nil
                  && (error.code == AMapLocationErrorReGeocodeFailed
                      || error.code == AMapLocationErrorTimeOut
                      || error.code == AMapLocationErrorCannotFindHost
                      || error.code == AMapLocationErrorBadURL
                      || error.code == AMapLocationErrorNotConnectedToInternet
                      || error.code == AMapLocationErrorCannotConnectToHost))
         {
             //逆地理错误：在带逆地理的单次定位中，逆地理过程可能发生错误，此时location有返回值，regeocode无返回值
             code = -1;
             if (AppTool::getInstance()->getAmapLocationDelegate() != NULL)
             {
                 AppTool::getInstance()->getAmapLocationDelegate()->onOnceLocationEnd(-1, 0.0, 0.0, "", "", "", "", "", "", "", "");
             }
         }
         else
         {
             code = 0;
             if (AppTool::getInstance()->getAmapLocationDelegate() != NULL)
             {
                 AppTool::getInstance()->getAmapLocationDelegate()->onOnceLocationEnd(code, location.coordinate.latitude, location.coordinate.longitude, [regeocode.formattedAddress UTF8String], [regeocode.province UTF8String], [regeocode.city UTF8String], [regeocode.district UTF8String], [regeocode.street UTF8String], [regeocode.number UTF8String], [regeocode.POIName UTF8String], [regeocode.adcode UTF8String]);
             }
         }
     }];
}

//持续定位
-(void)startLocation:(int)interval
{
    //[self._locManager setDistanceFilter:10];
    [self._locManager setLocatingWithReGeocode:YES];
    [self._locManager startUpdatingLocation];
}

//停止定位
-(void)stopLocation
{
    [self._locManager stopUpdatingLocation];
}

/**
 *  当定位发生错误时，会调用代理的此方法。
 *
 *  @param manager 定位 AMapLocationManager 类。
 *  @param error 返回的错误，参考 CLError 。
 */
- (void)amapLocationManager:(AMapLocationManager *)manager didFailWithError:(NSError *)error
{
    if (AppTool::getInstance()->getAmapLocationDelegate())
    {
        AppTool::getInstance()->getAmapLocationDelegate()->onLocationUpdate(-1, 0, 0, "", "", "", "", "", "", "", "");
    }
}

/**
 *  @brief 连续定位回调函数.注意：如果实现了本方法，则定位信息不会通过amapLocationManager:didUpdateLocation:方法回调。
 *
 *  @param manager 定位 AMapLocationManager 类。
 *  @param location 定位结果。
 */
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode;
{
    if (location != nil && reGeocode != nil)
    {
        if (AppTool::getInstance()->getAmapLocationDelegate())
        {
            AppTool::getInstance()->getAmapLocationDelegate()->onLocationUpdate(0, location.coordinate.latitude, location.coordinate.longitude, [reGeocode.formattedAddress UTF8String], [reGeocode.province UTF8String], [reGeocode.city UTF8String], [reGeocode.district UTF8String], [reGeocode.street UTF8String], [reGeocode.number UTF8String], [reGeocode.POIName UTF8String], [reGeocode.adcode UTF8String]);
        }
    }
    else
    {
        if (AppTool::getInstance()->getAmapLocationDelegate())
        {
            AppTool::getInstance()->getAmapLocationDelegate()->onLocationUpdate(-1, 0, 0, "", "", "", "", "", "", "", "");
        }
    }
}

- (void)dealloc
{
    if (self._locManager != nil)
    {
        [self._locManager stopUpdatingLocation];
        [self._locManager setDelegate:nil];
        [self._locManager release];
        self._locManager = nil;
    }
    
    [super dealloc];
}

@end
